<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据库分库分表技术详解</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb 0%, #4a6cf7 100%);
            color: white;
        }
        .card {
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
        }
        .section-title {
            position: relative;
            padding-bottom: 15px;
        }
        .section-title:after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 50px;
            height: 3px;
            background: #4a6cf7;
        }
        .diagram-container {
            background: #f8fafc;
            border-radius: 8px;
            padding: 20px;
            margin: 20px 0;
        }
        .highlight-box {
            border-left: 4px solid #4a6cf7;
            background: #f8fafc;
            padding: 15px;
            margin: 20px 0;
        }
        .feature-icon {
            font-size: 2rem;
            color: #4a6cf7;
            margin-bottom: 15px;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6 font-serif">数据库分库分表技术详解</h1>
            <p class="text-xl md:text-2xl mb-8 opacity-90">应对海量数据存储的分布式解决方案</p>
            <div class="flex justify-center space-x-4">
                <a href="#intro" class="bg-white text-blue-600 px-6 py-3 rounded-md font-medium hover:bg-blue-50 transition">开始探索</a>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container mx-auto max-w-5xl px-4 py-12">
        <!-- Introduction Section -->
        <section id="intro" class="mb-16">
            <h2 class="text-3xl font-bold mb-8 section-title font-serif">背景</h2>
            <div class="bg-white rounded-lg shadow-md p-8 card">
                <p class="text-lg mb-6">在互联网海量数据时代的今天，我们需要存储的数据也越来越多，在使用关系型数据库例如mysql等时，单表所需要存储的数据也越来越多，但是关系型数据库在单表数据库量较大的情况下，单表性能会急剧下降，面对这个问题，常见的做法就是进行分表，但是单纯的分表只能减少单表的压力，不能减轻数据库的压力，所以在分表的同时往往也会进行分库操作。</p>
                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1708237598368-670b831e-f9f4-4d60-b369-ea1b054842d8.png" alt="数据库压力示意图" class="w-full rounded-md shadow-sm mt-6">
            </div>
        </section>

        <!-- Overview Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 section-title font-serif">分库分表概述</h2>
            <div class="bg-white rounded-lg shadow-md p-8 card">
                <p class="text-lg mb-6">分库分表主要是为了解决互联网应用的大数据量存储问题，分表通常分为：垂直划分、水平划分；垂直划分通常是根据业务场景将一个多字段大表拆分成多个多个少字段小表，水平划分是根据某个分片策略将同一个表的数据分开存到多个相同结构表中。</p>
                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1708238840831-038be416-636d-4e83-acbd-358f9f2c53cd.png" alt="分库分表示意图" class="w-full rounded-md shadow-sm mt-6">
            </div>
        </section>

        <!-- Concept Explanation -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 section-title font-serif">分库分表概念的理解</h2>
            <p class="text-lg mb-8">分库分表只是笼统的说法，我们可以把他当成三个维度来看分别是：</p>
            
            <div class="grid md:grid-cols-3 gap-6">
                <!-- 分库 -->
                <div class="bg-white rounded-lg shadow-md p-6 text-center card">
                    <div class="feature-icon">
                        <i class="fas fa-database"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-3">分库</h3>
                    <p class="mb-4">将数据按照一定的规则分散存储到不同的数据库实例中。分库的主要目的是通过水平扩展来提高数据库系统的处理能力和存储容量。</p>
                    <img src="https://cdn.nlark.com/yuque/0/2022/png/179989/1670208495846-9b994109-fee3-4085-a147-cc61bdc32ad0.png" alt="分库示意图" class="w-full rounded-md shadow-sm">
                </div>
                
                <!-- 分表 -->
                <div class="bg-white rounded-lg shadow-md p-6 text-center card">
                    <div class="feature-icon">
                        <i class="fas fa-table"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-3">分表</h3>
                    <p class="mb-4">将数据按照一定的规则分散存储到不同的数据表中。分表的主要目的是通过减少单个数据表的数据量，提高查询效率和减轻单表的压力。</p>
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1708238468879-6b6da7b8-8b98-4121-a0f3-f59261e8e6e7.png" alt="分表示意图" class="w-full rounded-md shadow-sm">
                </div>
                
                <!-- 分库分表 -->
                <div class="bg-white rounded-lg shadow-md p-6 text-center card">
                    <div class="feature-icon">
                        <i class="fas fa-project-diagram"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-3">既分库又分表</h3>
                    <p class="mb-4">在某些情况下，需要同时进行分库和分表操作，以应对大规模数据量和高并发访问的需求。</p>
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1708238555683-9dc58f5e-3545-45bc-b9d2-c9f501d588a8.png" alt="分库分表示意图" class="w-full rounded-md shadow-sm">
                </div>
            </div>
        </section>

        <!-- Vertical Split -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 section-title font-serif">垂直拆分</h2>
            <div class="grid md:grid-cols-2 gap-8">
                <div>
                    <div class="bg-white rounded-lg shadow-md p-8 card">
                        <p class="text-lg mb-4">垂直拆分就是根据不同的业务，分为不同的数据库，比如会员数据库、订单数据库、支付数据库等，垂直拆分在大型电商系统中用的非常常见。</p>
                        <div class="highlight-box">
                            <p class="font-medium mb-2">优点：</p>
                            <p>拆分后业务清晰，拆分规则明确，系统之间整合或扩展容易。</p>
                            <p class="font-medium mt-4 mb-2">缺点：</p>
                            <p>部分业务表无法关联查询，只能通过接口方式通讯解决，提高了系统复杂度，存在分布式事务问题。</p>
                        </div>
                    </div>
                </div>
                <div>
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1708238635001-3a2cc937-91d4-413f-9ffc-9b5b337e17e8.png" alt="垂直拆分示意图" class="w-full rounded-md shadow-sm h-full object-cover">
                </div>
            </div>
        </section>

        <!-- Horizontal Split -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 section-title font-serif">水平拆分</h2>
            <div class="grid md:grid-cols-2 gap-8">
                <div>
                    <img src="https://cdn.nlark.com/yuque/0/2022/png/179989/1670208542036-a5ab54d1-f7d1-4e91-a79f-35ad6b112e09.png" alt="水平拆分示意图" class="w-full rounded-md shadow-sm h-full object-cover">
                </div>
                <div>
                    <div class="bg-white rounded-lg shadow-md p-8 card">
                        <p class="text-lg mb-4">水平拆分是把同一个表拆到不同的数据库中，进行数据均摊。相对于垂直拆分，水平拆分不是将表的数据做分类，而是按照某个字段的某种规则来分散到多个库之中，每个表中包含一部分数据。</p>
                        <p class="text-lg mb-4">简单来说，我们可以将数据的水平切分理解为是按照数据行的切分，就是将表中的某些行切分到一个数据库，而另外的某些行又切分到其他的数据库中，主要有分表，分库两种模式。该方式提高了系统的稳定性跟负载能力，但是跨库关联查询性能较差。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Dimension Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 section-title font-serif">分库分表维度</h2>
            <div class="grid md:grid-cols-2 gap-6">
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-xl font-bold mb-3 text-blue-600">垂直分库</h3>
                    <p>可以把多个表按业务耦合松紧归类，分别存放在不同的库，这些库可以分布在不同服务器，从而使访问压力被多服务器负载，大大提升性能，同时能提高整体架构的业务清晰度，不同的业务库可根据自身情况定制优化方案。但是它需要解决跨库带来的所有复杂问题。</p>
                </div>
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-xl font-bold mb-3 text-blue-600">垂直分表</h3>
                    <p>可以把一个宽表的字段按访问频次、是否是大字段的原则拆分为多个表，这样既能使业务清晰，还能提升部分性能。拆分后，尽量从业务角度避免联查，否则性能方面将得不偿失。</p>
                </div>
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-xl font-bold mb-3 text-blue-600">水平分库</h3>
                    <p>可以把一个表的数据(按数据行)分到多个不同的库，每个库只有这个表的部分数据，这些库可以分布在不同服务器，从而使访问压力被多服务器负载，大大提升性能。它不仅需要解决跨库带来的所有。</p>
                </div>
                <div class="bg-white rounded-lg shadow-md p-6 card">
                    <h3 class="text-xl font-bold mb-3 text-blue-600">水平分表</h3>
                    <p>可以把一个表的数据(按数据行)分到多个同一个数据库的多张表中，每个表只有这个表的部分数据，这样做能小幅提升性能，它仅仅作为水平分库的一个补充优化。</p>
                </div>
            </div>
            <div class="bg-white rounded-lg shadow-md p-6 mt-6 card">
                <p class="text-lg">一般来说，在系统设计阶段就应该根据业务耦合松紧来确定垂直分库，垂直分表方案，在数据量及访问压力不是特别大的情况，首先考虑缓存、读写分离、索引技术等方案。若数据量极大，且持续增长，再考虑水平分库水平分表方案。</p>
            </div>
        </section>

        <!-- Algorithm Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 section-title font-serif">分库分表算法</h2>
            <div class="bg-white rounded-lg shadow-md p-8 card">
                <p class="text-lg mb-6">分库分表会导致一张表存储在多个数据库中，因此需要一种路由算法来确定具体的存储位置。常见的路由算法包括取模算法、范围限定算法、范围加取模算法和预定义算法。</p>
                
                <div class="grid md:grid-cols-2 gap-6">
                    <!-- 取模算法 -->
                    <div class="bg-gray-50 rounded-lg p-6">
                        <h3 class="text-xl font-bold mb-3 text-blue-600">取模算法</h3>
                        <p class="mb-4">根据数据的某种特征值对数据库数量取模，以确定数据存储在哪个数据库中。</p>
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/179989/1670208577088-0d80559e-d971-47e2-a673-760f193c9aea.png" alt="取模算法示意图" class="w-full rounded-md shadow-sm">
                    </div>
                    
                    <!-- 范围限定算法 -->
                    <div class="bg-gray-50 rounded-lg p-6">
                        <h3 class="text-xl font-bold mb-3 text-blue-600">范围限定算法</h3>
                        <p class="mb-4">根据某些范围字段，比如时间或者ID区间，对数据进行拆分和划分。</p>
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/179989/1670208604533-2e46d7a4-e170-4bac-b9ac-1164ebb47847.png" alt="范围限定算法示意图" class="w-full rounded-md shadow-sm">
                    </div>
                    
                    <!-- 范围+取模算法 -->
                    <div class="bg-gray-50 rounded-lg p-6">
                        <h3 class="text-xl font-bold mb-3 text-blue-600">范围 + 取模算法</h3>
                        <p class="mb-4">为了解决热点数据的问题，我们对范围算法进行了优化。现在，每个库的用户表t_user只存放1000万条数据。在每个库里，我们再将用户表t_user按照一定规则拆分成多个子表，然后根据userID进行取模路由到相应的子表中。</p>
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/179989/1670208624044-97fe505e-a411-4b31-9e78-b800393afb71.png" alt="范围加取模算法示意图" class="w-full rounded-md shadow-sm">
                    </div>
                    
                    <!-- 地域分片 -->
                    <div class="bg-gray-50 rounded-lg p-6">
                        <h3 class="text-xl font-bold mb-3 text-blue-600">地域分片</h3>
                        <p class="mb-4">地理位置分片是一种更广泛的数据划分方式，它按照城市或地域的不同将数据分配到不同的分片库和表中。</p>
                        <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1708240867745-d9b2c21a-1d24-47ce-ac27-3f91190db289.png" alt="地域分片示意图" class="w-full rounded-md shadow-sm">
                    </div>
                </div>
            </div>
        </section>
    </div>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-8">
        <div class="container mx-auto max-w-5xl px-4 text-center">
            <p class="mb-2">技术小馆</p>
            <a href="http://www.yuque.com/jtostring" class="text-blue-300 hover:text-blue-100 transition">http://www.yuque.com/jtostring</a>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>